import { defineStore } from 'pinia'
import { reactive, toRef } from 'vue'

import { useTokenStore } from './token'
import { queryClient } from '@/apis/client'
import { Role, roleIsEnabled } from '@/constants/role'
import { ApiGetUserInfo, KeyApiGetUserInfo, UserCustomCode, type UserProfile } from '@/apis/user'

export const useUserStore = defineStore('user', () => {
  const InitialUserProfile: UserProfile = {
    name: '',
    username: '',
    role: Role.None
  }

  const user = reactive<UserProfile>({ ...InitialUserProfile })
  const patchUserInfo = ({ name, role, username }: UserProfile) => {
    user.name = name
    user.role = role
    user.username = username
  }

  const tokenStore = useTokenStore()
  const hasLogin = toRef(tokenStore, 'hasRefreshToken')

  const logout = () => {
    tokenStore.setToken('', '')
    console.log('logout')
    patchUserInfo({ ...InitialUserProfile })
  }

  /** 当前用户是否支持指定的role权限 */
  const isEnabled = (role: number) => roleIsEnabled(user.role, role)

  const updateUserInfo = async (): Promise<boolean> => {
    if (!hasLogin.value) {
      return false
    }

    await tokenStore.initiatePromise

    const { data, code } = await queryClient
      .fetchQuery({
        queryKey: KeyApiGetUserInfo,
        queryFn: ApiGetUserInfo
      })
      .catch(() => ({
        code: 0,
        data: { ...InitialUserProfile }
      }))

    if (code !== UserCustomCode.GetProfileSuccess) {
      logout()
      return false
    } else {
      patchUserInfo(data)
      return true
    }
  }

  tokenStore.afterRefreshAccessToken((token) => (token === '' ? logout() : updateUserInfo()))

  const login = async (access: string, refresh: string) => {
    tokenStore.setToken(access, refresh)
    return updateUserInfo()
  }

  return {
    user: user as Readonly<typeof user>,
    hasLogin,

    login,
    logout,
    isEnabled,
    updateUserInfo
  }
})
